package com.tepth.remote.control.base.refresh;

import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.tepth.remote.control.R;
import com.tepth.remote.control.base.config.ApiDictionary;
import com.tepth.remote.control.manager.ConfigManager;
import com.tepth.remote.core.net.callback.IError;
import com.tepth.remote.core.net.callback.ISoapSuccess;
import com.tepth.remote.core.net.callback.ISuccess;
import com.tepth.remote.core.net.retrofit.RxRetrofitClient;
import com.tepth.remote.core.net.soap.SoapClient;
import com.tepth.remote.ui.recycler.BaseDataConverter;
import com.tepth.remote.ui.recycler.MultipleItemEntity;
import com.tepth.remote.ui.recycler.MultipleRecyclerAdapter;
import com.tepth.remote.ui.recycler.MultipleRecyclerClickListener;

import org.ksoap2.serialization.SoapObject;

import java.util.ArrayList;
import java.util.WeakHashMap;

/**
 * Description:
 *
 * @author Hequn.Lee
 * @date 2018/11/22
 */
public class RefreshHandler implements
        SwipeRefreshLayout.OnRefreshListener,
        BaseQuickAdapter.RequestLoadMoreListener {

    private final SwipeRefreshLayout REFRESH;
    private final PagingBean BEAN;
    private final RecyclerView RECYCLERVIEW;
    private MultipleRecyclerAdapter mAdapter;
    private final BaseDataConverter CONVERTER;
    private final String METHOD;
    private final MultipleRecyclerClickListener CLICK;
    private final int REQUEST_CODE;
    /**
     * 请求方式  1为SOAP请求，2为Retrofit请求
     */
    private final int REQUEST_TYPE;

    private RefreshHandler(SwipeRefreshLayout refreshLayout,
                           RecyclerView recyclerView,
                           BaseDataConverter converter,
                           PagingBean bean,
                           String methodName,
                           MultipleRecyclerClickListener mClickListener,
                           int requestSuccessCode,
                           int requestType) {
        this.REFRESH = refreshLayout;
        this.RECYCLERVIEW = recyclerView;
        this.CONVERTER = converter;
        this.BEAN = bean;
        this.METHOD = methodName;
        this.CLICK = mClickListener;
        this.REQUEST_CODE = requestSuccessCode;
        this.REQUEST_TYPE = requestType;
        mAdapter = MultipleRecyclerAdapter.create(new ArrayList<MultipleItemEntity>(), CLICK);
        mAdapter.setEmptyView(R.layout.view_empty, RECYCLERVIEW);
        mAdapter.setOnLoadMoreListener(RefreshHandler.this, RECYCLERVIEW);
        REFRESH.setOnRefreshListener(this);
        RECYCLERVIEW.setAdapter(mAdapter);
    }

    public static RefreshHandler create(SwipeRefreshLayout refreshLayout,
                                        RecyclerView recyclerView,
                                        BaseDataConverter converter,
                                        String methodName,
                                        MultipleRecyclerClickListener mClickListener,
                                        int requestSuccessCode,
                                        int requestType) {

        return new RefreshHandler(refreshLayout,
                recyclerView,
                converter,
                new PagingBean(),
                methodName,
                mClickListener,
                requestSuccessCode,
                requestType);
    }

    @Override
    public void onRefresh() {
        BEAN.setPageIndex(0);
        mAdapter.setEnableLoadMore(false);
        if (REQUEST_TYPE == 1) {
            requestSoapData(true, null);
        } else {
            requestRetrofitData(true, null);
        }
    }

    public void firstLoadData(RefreshCallback callback) {
        BEAN.setPageIndex(0);
        mAdapter.setEnableLoadMore(false);
        if (REQUEST_TYPE == 1) {
            requestSoapData(true, callback);
        } else {
            requestRetrofitData(true, callback);
        }
    }

    public void requestSoapData(final boolean isRefresh, final RefreshCallback callback) {
        final WeakHashMap<String, Object> params = new WeakHashMap<>();
        params.put("u", ConfigManager.getInstance().getUid() + "");
        params.put("i", BEAN.getPageIndex());
        params.put("s", BEAN.getPageSize());
        SoapClient.builder()
                .methodName(METHOD)
                .params(params)
                .nameSpace(ApiDictionary.SOAP_NAME_SPACE)
                .success(new ISoapSuccess() {
                    @Override
                    public void onSuccess(final SoapObject object) {
                        final int code = Integer.parseInt(object.getProperty("Code").toString());
                        if (code == REQUEST_CODE) {
                            final int totalCount = Integer.parseInt(object.getPropertySafelyAsString("Text"));
                            final SoapObject value = (SoapObject) object.getProperty("Value");
                            ArrayList<Object> data = new ArrayList<>();
                            final int size = value.getPropertyCount();
                            for (int i = 0; i < size; i++) {
                                data.add(value.getProperty(i));
                            }
                            if (isRefresh) {
                                mAdapter.setEnableLoadMore(true);
                                mAdapter.getData().clear();
                                CONVERTER.clearData();
                                mAdapter.addData(CONVERTER.setData(data).convert());
                                BEAN.setCurrentCount(data.size());
                                REFRESH.setRefreshing(false);
                                if (callback != null) {
                                    callback.onRefreshCallback();
                                }
                            } else {
                                CONVERTER.clearData();
                                mAdapter.addData(CONVERTER.setData(data).convert());
                                BEAN.setCurrentCount(BEAN.getCurrentCount() + data.size());
                            }
                            BEAN.setTotal(totalCount);
                            if (BEAN.getCurrentCount() < BEAN.getTotal()) {
                                mAdapter.loadMoreComplete();
                            } else {
                                mAdapter.loadMoreEnd();
                            }
                            BEAN.addIndex();
                        }
                    }
                })
                .error(new IError() {
                    @Override
                    public void onError(int code, String msg) {
                        if (callback != null) {
                            callback.onRefreshCallback();
                        }
                        CLICK.onLoadRecyclerError(msg);
                    }
                })
                .builder()
                .post();
    }

    public void requestRetrofitData(final boolean isRefresh, final RefreshCallback callback) {
        RxRetrofitClient.builder()
                .url(METHOD)
                .params("u", ConfigManager.getInstance().getUid())
                .params("i", BEAN.getPageIndex())
                .params("s", BEAN.getPageSize())
                .success(new ISuccess() {
                    @Override
                    public void onSuccess(Object value) {
                        JSONObject jsonObject = JSONObject.parseObject((String) value);
                        int resultCode = jsonObject.getInteger("Code");
                        if (resultCode == REQUEST_CODE) {
                            JSONArray resultValue = jsonObject.getJSONArray("Value");
                            final int totalCount = Integer.parseInt(jsonObject.getString("Text"));
                            final int size = resultValue.size();
                            ArrayList<Object> data = new ArrayList<>();
                            for (int i = 0; i < size; i++) {
                                data.add(resultValue.get(i));
                            }
                            if (isRefresh) {
                                mAdapter.setEnableLoadMore(true);
                                mAdapter.setNewData(CONVERTER.setData(data).convert());
                                BEAN.setCurrentCount(data.size());
                                REFRESH.setRefreshing(false);
                                if (callback != null) {
                                    callback.onRefreshCallback();
                                }
                            } else {
                                if (mAdapter == null) {
                                    mAdapter = MultipleRecyclerAdapter.create(CONVERTER.setData(data), CLICK);
                                    mAdapter.setOnLoadMoreListener(RefreshHandler.this, RECYCLERVIEW);
                                    RECYCLERVIEW.setAdapter(mAdapter);
                                } else {
                                    mAdapter.addData(CONVERTER.setData(data).convert());
                                }
                                BEAN.setCurrentCount(BEAN.getCurrentCount() + data.size());

                            }
                            BEAN.setTotal(totalCount);
                            if (BEAN.getCurrentCount() < BEAN.getTotal()) {
                                mAdapter.loadMoreComplete();
                            } else {
                                mAdapter.loadMoreEnd();
                            }
                            BEAN.addIndex();
                        }
                    }
                })
                .error(new IError() {
                    @Override
                    public void onError(int code, String msg) {
                        if (callback != null) {
                            callback.onRefreshCallback();
                        }
                        CLICK.onLoadRecyclerError(msg);
                    }
                })
                .builder()
                .getOriginal();
    }

    @Override
    public void onLoadMoreRequested() {
        if (REQUEST_TYPE == 1) {
            requestSoapData(false, null);
        } else {
            requestRetrofitData(false, null);
        }
    }

    public MultipleRecyclerAdapter getAdapter() {
        return mAdapter;
    }
}
